#include "Rotation.h"
#include <string>
#include "Ability.h"
#include <iostream>
#include <algorithm>
#include <complex>
#include <time.h>
#include "ui_mainwindow.h"
#include "mainwindow.h"
using namespace std;

enum STATS {
    AIM = 0, CUNNING, STRENGTH, WILLPOWER = 3,
    CRIT, SURGE, ALACRITY , POWER , ACCURACY = 8,
    DEFENSE, SHIELD, ABSORB, ARMOR = 12,
    LEVEL, MH_ACC, OH_ACC, ENEMY_LEVEL, ENEMY_ARMOR= 17,
    SPEED,  MH_MAX, MH_MIN, OH_MAX , OH_MIN =22,
    TECH_CRIT_CHANCE , TECH_CRIT_SIZE, TECH_BONUS_HEALING, TECH_BONUS_DAMAGE = 26,
    RANGED_CRIT_CHANCE , RANGED_CRIT_SIZE, RANGED_BONUS_DAMAGE = 29,
    FORCE_CRIT_CHANCE , FORCE_CRIT_SIZE, FORCE_BONUS_HEALING, FORCE_BONUS_DAMAGE = 33,
    MELEE_CRIT_CHANCE , MELEE_CRIT_SIZE, MELEE_BONUS_DAMAGE = 36,
    TECH_POWER, FORCE_POWER = 38
};

double getAmmoRegened(double Ammo, Ability abil, double eTime, double &regenTime){
    double rAmmo = 0;
    //implement passive regen during casting
    bool isInstant = abil.getIsInstant();

    if(Ammo == 12){
        if(isInstant == false){rAmmo =0;}
        if(isInstant == true){ rAmmo =  0.6 * 1.5;}
        regenTime = eTime;
    }else{
        while ((eTime-regenTime)>0.5){
            if ((Ammo+rAmmo) >= 8) {
                rAmmo += 0.6 * 0.5;
                regenTime += 0.5;
            } else {
                if ((Ammo+rAmmo) >= 3) {
                    rAmmo += 0.36 * 0.5;
                    regenTime += 0.5;
                } else {
                    rAmmo += 0.24 * 0.5;
                    regenTime += 0.5;
                }
            }
        }
    }
    return rAmmo;
}

double getAmmoRegened(double Ammo, Ability abil, double speed)
{
    bool isInstant = abil.getIsInstant();
    double tTime = abil.getCastTime(speed);
    double rAmmo = 0;
    //implement passive regen during casting
    if(Ammo == 12){
        if(isInstant == false) rAmmo =0;
        if(isInstant == true) rAmmo =  0.6 * 1.5;
    }else{
        if (Ammo >= 8) {
            rAmmo += 0.6 * tTime;
        } else {
            if (Ammo >= 3) {
                rAmmo += 0.36 * tTime;
            } else {
                rAmmo += 0.24 * tTime;
            }
        }
    }

    return rAmmo;
}
double getHeatRegened(double Heat, Ability abil, double eTime, double &regenTime){
    double rHeat = 0;
    //implement passive regen during casting
    bool isInstant = abil.getIsInstant();
    while ((eTime-regenTime)>=0.5){
        if(Heat == 0){
            if(isInstant == false) rHeat =0;
            if(isInstant == true) rHeat =  5 * 1.5;
            regenTime = eTime;
        }else{
            if (Heat <= 39) {
                rHeat += 5 * 0.5;
                regenTime += 0.5;
            } else {
                if (Heat <= 80) {
                    rHeat += 3 * 0.5;
                    regenTime += 0.5;
                } else {
                    rHeat += 2 * 0.5;
                    regenTime += 0.5;
                }
            }
        }
    }
    return rHeat;
}

double getHeatRegened(double Heat, Ability abil, double speed){
    bool isInstant = abil.getIsInstant();
    double tTime = abil.getCastTime(speed);
    double rHeat = 0;
    //implement passive regen during casting
    if(Heat == 0){
        if(isInstant == false) rHeat =0;
        if(isInstant == true) rHeat =  5 * 1.5;
    }else{
        if (Heat <= 39) {
            rHeat = 5 * tTime;
        } else {
            if (Heat <= 80) {
                rHeat = 3 * tTime;
            } else {
                rHeat = 2 * tTime;
            }
        }
    }

    return rHeat;
}

double getEnergyRegened(double Energy, Ability abil, double eTime, double &regenTime, double &pugTime, double &pugRemaining)
{
    double rEnergy = 0;
    //implement passive regen during casting
    bool isInstant = abil.getIsInstant();
    while ((eTime-regenTime)>=0.5){
        if(Energy == 100){
            if(isInstant == false) {rEnergy =0;}
            if(isInstant == true){ rEnergy =  5 * 1.5;}
            regenTime = eTime;
        }else{
            if (Energy >= 60) {
                rEnergy += 5 * 0.5;
                regenTime += 0.5;
            } else {
                if (Energy >= 20) {
                    rEnergy += 3 * 0.5;
                    regenTime += 0.5;
                } else {
                    rEnergy += 2 * 0.5;
                    regenTime += 0.5;
                }
            }
        }
    }
    while(((eTime-pugTime)>=3)&&(pugRemaining>0.0)){
        //if(){
        rEnergy += 3;
        pugTime +=3;
        pugRemaining -=3;
    }
    pugRemaining = max(pugRemaining, 0.0);
    return rEnergy;
}

double getEnergyRegened(double Energy, Ability abil, double speed){
    double rEnergy = 0;
    //implement passive regen during casting
    bool isInstant = abil.getIsInstant();
    double tTime = abil.getCastTime(speed);
    if(Energy == 100){
        if(isInstant == false) {rEnergy =0;}
        if(isInstant == true){ rEnergy =  5 * tTime;}
    }else{
        if (Energy >= 60) {
            rEnergy = 5 * tTime;
        } else {
            if (Energy >= 20) {
                rEnergy = 3 * tTime;
            } else {
                rEnergy = 2 * tTime;
            }
        }
    }

    return rEnergy;
}

bool Proc(double threshold)
{
    //initialize random number generator
    /*srand( time(NULL))*/;
    //rand(); rand(); rand(); rand(); rand();
    //roll a random number
    double roll = rand() % 100 + 1;
    bool proc = false;
    if(roll<=threshold) proc = true;

    return proc;
}
